# -*- coding: utf-8 -*-
"""
# @created on : 9月 2021/9/15 00:56
# @author     : kevin
# @file       : get_excel_data.py
# @software   : PyCharm
# @project    : auto_interface_test


@license: (C) Copyright 2019-2025, Corporation Limited.
@desc:
"""
from utils.operation_excel import OperationExcel
from urllib.parse import urljoin
from common.logger import Logger
import pandas as pd


class GetExcelData:
    def __init__(self):
        """
        实例化多个sheet，在调用的时候直接调用获取相应sheet的内容
        """
        self.suit = OperationExcel(sheet_name='suit')
        self.case = OperationExcel(sheet_name='case')
        self.data = OperationExcel(sheet_name='data')
        self.data_type = OperationExcel(sheet_name='type')
        self.log = Logger()

    def my_return(self, ret):
        """
        判断传入值是否为缺失值，不是就返回相应值，是则返回None
        :param ret: 传入值
        :return: 取值，确实则返回None
        """
        flg = None
        if pd.notnull(ret):
            flg = ret
        return flg

    def get_suit_lines(self):
        """
        获取suit数
        :return: suit数量
        """
        return self.suit.get_lines()

    def get_case_lines(self):
        """
        获取case接口用例数
        :return: 接口用例数量
        """
        return self.case.get_lines()

    def get_data_lines(self):
        """
        获取数据用例数
        :return: 数据用例数量
        """
        return self.data.get_lines()

    def get_ele_lines(self):
        """
        获取element数量
        :return: element数量
        """
        return self.element.get_lines()

    def get_suit_is_run(self, suit_id):
        """
        通过suit ID获取suit是否执行
        :param suit_id: suit ID
        :return: 需要执行返回True， 否则返回False
        """
        run_model = self.suit.get_cell_value(suit_id, '是否执行')
        return self.my_return(run_model)

    def get_case_is_run(self, case_id):
        """
        通过case ID获取case是否需要执行
        :param case_id: case ID
        :return: 需要执行返回True， 否则返回False
        """
        run_model = self.case.get_cell_value(case_id, '是否执行')
        return self.my_return(run_model)

    def get_data_is_run(self, row):
        """
        通过数据行获取数据是否需要执行
        :param row: sheet[data]的用例ID
        :return: 需要执行返回True， 否则返回False
        """
        run_model = self.data.get_cell_value(row, '是否执行')
        return self.my_return(run_model)

    def with_cookie(self, id):
        """
        通过ID判断接口是否需要在返回数据中获取cookie
        :param id: 行号
        :return: 需要带入header返回True， 否则返回False
        """
        cookie = self.case.get_cell_value(id, '是否获取cookie')
        return self.my_return(cookie)

    def get_cookie_by_data(self, id):
        """
        通过data的id获取对应case中的接口是否需要在返回数据中获取cookie
        :param id: data id
        :return: 需要header返回True， 否则返回False
        """
        case_id = self.get_case_by_data(id)
        cookie = self.with_cookie(case_id)
        return self.my_return(cookie)

    def with_token(self, id):
        """
        通过ID判断接口是否需要在返回数据中获取token
        :param id: 行号
        :return: 需要带入header返回True， 否则返回False
        """
        token = self.case.get_cell_value(id, '是否获取token')
        return self.my_return(token)

    def get_token_by_data(self, id):
        """
        通过data的id获取对应case中的接口是否需要在返回数据中获取token
        :param id: data id
        :return: 需要header返回True， 否则返回False
        """
        case_id = self.get_case_by_data(id)
        token = self.with_token(case_id)
        return self.my_return(token)

    def get_request_method(self, id):
        """
        通过id获取请求方式
        :param id: id
        :return: 请求方式
        """
        request_method = self.case.get_cell_value(id, '请求类型')
        return self.my_return(request_method)

    def get_request_url(self, id):
        """
        通过id获取接口对应的url
        :param id: id
        :return: 拼接后的接口
        """
        domain = self.my_return(self.case.get_cell_value(id, '域名'))
        interface = self.my_return(self.case.get_cell_value(id, '接口'))
        try:
            if interface is not None:
                url = urljoin(str(domain), str(interface))
            else:
                url = str(domain)
        except (AttributeError, TypeError) as e:
            self.log.logger('error', f'获取url错误，传入行为{id}, 错误信息为{e}')
        finally:
            return self.my_return(url)

    def get_data(self, id):
        """
        通过id获取data里的请求数据
        :param id:
        :return: 请求数据
        """
        request_data = self.data.get_cell_value(id, '请求数据')
        return self.my_return(request_data)

    def get_case_by_data(self, id):
        """
        通过id获取case的id
        :param id: data id
        :return: case id
        """
        case_id = self.data.get_cell_value(id, '模块ID')
        return self.my_return(case_id)

    def get_suit_by_case(self, id):
        """
        通过case id 获取 suit id
        :param id: case id
        :return: suit id
        """
        suit_id = self.case.get_cell_value(id, '套件ID')
        return self.my_return(suit_id)

    def get_expect_data(self, id):
        """
        获取预期结果数据
        :param id: 数据ID
        :return: 预期结果值，预期为空则返回None
        """
        expect_data = self.data.get_cell_value(id, '预期结果')
        return self.my_return(expect_data)

    def get_url_by_data(self, id):
        """
        通过数据ID获取case中的URL值
        :param id: 数据ID
        :return: 数据对应case的url
        """
        case_id = self.get_case_by_data(id)
        url = self.get_request_url(case_id)
        return self.my_return(url)

    def get_method_by_data(self, id):
        """
        通过data 的id 获取对应case的请求方法
        :param id: data id
        :return: 对应case的请求方法
        """
        case_id = self.get_case_by_data(id)
        method = self.get_request_method(case_id)
        return self.my_return(method)

    def get_case_run_by_data(self, id):
        """
        通过data id 获取case是否需要执行
        :param id: data id
        :return: case需要执行返回True， 否则返回False
        """
        case_id = self.get_case_by_data(id)
        run_model = self.get_case_is_run(case_id)
        return self.my_return(run_model)

    def get_suit_run_by_case(self, id):
        """
        通过case id获取suit是否需要执行
        :param id: case id
        :return: suit需要执行返回True， 否则返回False
        """
        suit_id = self.get_suit_by_case(id)
        run_model = self.get_suit_is_run(suit_id)
        return self.my_return(run_model)

    def get_suit_run_by_data(self, id):
        """
        通过data id获取suit是否需要执行
        :param id: data id
        :return: suit 需要执行返回True，否则返回False
        """
        case_id = self.get_case_by_data(id)
        run_model = self.get_suit_run_by_case(case_id)
        return self.my_return(run_model)

    def get_request_data_model(self, id):
        """
        获取请求数据类型
        :param id: data id
        :return: 如果非空则返回实际数据类型，否则返回None
        """
        data_model = self.data.get_cell_value(id, '请求数据类型')
        return self.my_return(data_model)

    def get_need_data(self, id):
        """
        获取本条用例依赖的用例id
        :param id: data id
        :return: 被依赖data的id
        """
        nc = self.data.get_cell_value(id, '依赖数据')
        return self.my_return(nc)

    def get_data_back_key(self, id):
        """
        获取数据依赖字段数据
        :param id: data id
        :return: 数据依赖字段的值
        """
        back_value = self.data.get_cell_value(id, '数据提取参数')
        return self.my_return(back_value)

    def get_assert_type_by_id(self, id):
        """
        获取断言类型
        :param id: data id
        :return:
        """
        assert_type = self.data.get_cell_value(id, '断言类型')
        return self.my_return(assert_type)

    def get_res_meth(self, id):
        """
        获取实际结果中要获取到的返回值的表达式
        :param id: data id
        :return: json表达式
        """
        meth = self.data.get_cell_value(id, '实际结果')
        return self.my_return(meth)

    def get_data_type_mark_id(self, data_type):
        """
        通过类型查找对应的ID值，然后才可以在此基础上处理相关类型数据
        :param data_type: 取到的类型值
        :return: 该类型数据对应的ID
        """
        id = self.data_type.get_id_by_value(index='类型', value=data_type)
        return self.my_return(id)

    def get_type_mark_by_data_id(self, id):
        """
        通过data id获取元素标记的特殊标记值
        :param id: data id
        :return: 标记值
        """
        type_id = self.get_data_type_mark_id(self.get_request_data_model(id))
        mark = self.data_type.get_cell_value(type_id, '标记')
        return self.my_return(mark)

    def get_type_len_by_data_id(self, id):
        """
        通过data数据获取特殊类型元素标记的长度
        :param id: data id
        :return: 标记长度
        """
        type_id = self.get_data_type_mark_id(self.get_request_data_model(id))
        type_len = self.data_type.get_cell_value(type_id, '元素长度')
        return self.my_return(type_len)

    def get_req_type(self, id):
        """
        获取接口请求是资源类型
        :param id: 接口ID
        :return: 返回资源类型，为空则返回None
        """
        is_pic = self.case.get_cell_value(id, '请求头类型')
        return self.my_return(is_pic)

    def get_req_type_by_data_id(self, id):
        """
        通过data获取接口请求是资源类型
        :param id: data id
        :return: 返回资源类型，为空则返回None
        """
        case_id = self.get_case_by_data(id)
        is_pic = self.get_req_type(case_id)
        return self.my_return(is_pic)

    def get_dat_id_list_by_suit_id(self, id):
        """
        通过suit id获取到suit对应要执行的data数据列表
        :param id: suit id
        :return: data id list
        """
        id_list = []
        for i in range(1, self.get_data_lines()):
            if self.data.get_cell_value(i, '套件ID') == id:
                id_list.append(i)
        return id_list


